"""
D-Bus接口数据结构定义

定义用于存储D-Bus接口信息的数据类
"""

from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from enum import Enum


class AccessType(Enum):
    """D-Bus属性访问权限枚举"""
    READ = "read"
    WRITE = "write"
    READWRITE = "readwrite"


class ParameterDirection(Enum):
    """D-Bus方法参数方向枚举"""
    IN = "in"
    OUT = "out"


@dataclass
class Parameter:
    """D-Bus方法参数信息"""
    name: str                           # 参数名称
    type_signature: str                 # D-Bus类型签名
    direction: ParameterDirection       # 参数方向
    description: str = ""               # 参数描述
    
    def __post_init__(self):
        """初始化后处理"""
        if isinstance(self.direction, str):
            self.direction = ParameterDirection(self.direction)


@dataclass
class DBusMethod:
    """D-Bus方法信息"""
    name: str                           # 方法名称
    description: str = ""               # 方法描述
    input_params: List[Parameter] = field(default_factory=list)   # 输入参数
    output_params: List[Parameter] = field(default_factory=list)  # 输出参数
    exceptions: List[str] = field(default_factory=list)          # 可能抛出的异常
    annotations: Dict[str, str] = field(default_factory=dict)    # 注解信息
    
    @property
    def input_signature(self) -> str:
        """获取输入参数的类型签名"""
        return "".join(param.type_signature for param in self.input_params)
    
    @property
    def output_signature(self) -> str:
        """获取输出参数的类型签名"""
        return "".join(param.type_signature for param in self.output_params)


@dataclass
class DBusProperty:
    """D-Bus属性信息"""
    name: str                           # 属性名称
    type_signature: str                 # D-Bus类型签名
    access: AccessType                  # 访问权限
    description: str = ""               # 属性描述
    default_value: str = ""             # 默认值
    units: str = ""                     # 单位
    annotations: Dict[str, str] = field(default_factory=dict)    # 注解信息
    
    def __post_init__(self):
        """初始化后处理"""
        if isinstance(self.access, str):
            self.access = AccessType(self.access)


@dataclass
class DBusSignal:
    """D-Bus信号信息"""
    name: str                           # 信号名称
    description: str = ""               # 信号描述
    params: List[Parameter] = field(default_factory=list)       # 信号参数
    annotations: Dict[str, str] = field(default_factory=dict)   # 注解信息
    
    @property
    def signature(self) -> str:
        """获取信号的类型签名"""
        return "".join(param.type_signature for param in self.params)


@dataclass
class DBusInterface:
    """D-Bus接口信息"""
    name: str                           # 接口名称
    namespace: str                      # 命名空间
    description: str = ""               # 接口描述
    source_file: str = ""               # 源文件路径
    methods: List[DBusMethod] = field(default_factory=list)     # 方法列表
    properties: List[DBusProperty] = field(default_factory=list) # 属性列表
    signals: List[DBusSignal] = field(default_factory=list)     # 信号列表
    is_public: bool = True              # 是否为公共接口
    category: str = ""                  # 接口分类
    version: str = ""                   # 接口版本
    annotations: Dict[str, str] = field(default_factory=dict)   # 注解信息
    
    @property
    def method_count(self) -> int:
        """获取方法数量"""
        return len(self.methods)
    
    @property
    def property_count(self) -> int:
        """获取属性数量"""
        return len(self.properties)
    
    @property
    def signal_count(self) -> int:
        """获取信号数量"""
        return len(self.signals)
    
    def get_method_by_name(self, name: str) -> Optional[DBusMethod]:
        """根据名称获取方法"""
        for method in self.methods:
            if method.name == name:
                return method
        return None
    
    def get_property_by_name(self, name: str) -> Optional[DBusProperty]:
        """根据名称获取属性"""
        for prop in self.properties:
            if prop.name == name:
                return prop
        return None
    
    def get_signal_by_name(self, name: str) -> Optional[DBusSignal]:
        """根据名称获取信号"""
        for signal in self.signals:
            if signal.name == name:
                return signal
        return None


@dataclass
class DBusObject:
    """D-Bus对象信息（可包含多个接口）"""
    path: str                           # 对象路径
    interfaces: List[DBusInterface] = field(default_factory=list) # 接口列表
    description: str = ""               # 对象描述
    
    def add_interface(self, interface: DBusInterface):
        """添加接口"""
        self.interfaces.append(interface)
    
    def get_interface_by_name(self, name: str) -> Optional[DBusInterface]:
        """根据名称获取接口"""
        for interface in self.interfaces:
            if interface.name == name:
                return interface
        return None


@dataclass
class AnalysisResult:
    """分析结果汇总"""
    total_interfaces: int = 0           # 总接口数
    public_interfaces: int = 0          # 公共接口数
    total_methods: int = 0              # 总方法数
    total_properties: int = 0           # 总属性数
    total_signals: int = 0              # 总信号数
    categories: Dict[str, int] = field(default_factory=dict)     # 分类统计
    namespaces: Dict[str, int] = field(default_factory=dict)     # 命名空间统计
    interfaces: List[DBusInterface] = field(default_factory=list) # 接口列表
    errors: List[str] = field(default_factory=list)             # 错误信息
    warnings: List[str] = field(default_factory=list)           # 警告信息
    
    def add_interface(self, interface: DBusInterface):
        """添加接口到结果中"""
        self.interfaces.append(interface)
        self.total_interfaces += 1
        
        if interface.is_public:
            self.public_interfaces += 1
        
        self.total_methods += interface.method_count
        self.total_properties += interface.property_count
        self.total_signals += interface.signal_count
        
        # 更新分类统计
        category = interface.category or "未分类"
        self.categories[category] = self.categories.get(category, 0) + 1
        
        # 更新命名空间统计
        namespace = interface.namespace or "未知"
        self.namespaces[namespace] = self.namespaces.get(namespace, 0) + 1
    
    def add_error(self, error: str):
        """添加错误信息"""
        self.errors.append(error)
    
    def add_warning(self, warning: str):
        """添加警告信息"""
        self.warnings.append(warning)
